﻿using DocumentFormat.OpenXml.Lite.Core.Office;
using DocumentFormat.OpenXml.Lite.DrawingML.Chart;
using DocumentFormat.OpenXml.Lite.DrawingML.Chart.Properties;
using Samples.Drawing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Lite.WordprocessingML;
using EB = DocumentFormat.OpenXml.Lite.SpreadsheetML.Excel.Base;
using EWE = DocumentFormat.OpenXml.Lite.SpreadsheetML.Excel.WorksheetElements;
using ET = DocumentFormat.OpenXml.Lite.SpreadsheetML.Excel.Types;
using WB = DocumentFormat.OpenXml.Lite.WordprocessingML.Word.Base;
using WD = DocumentFormat.OpenXml.Lite.WordprocessingML.Drawing;
using WT = DocumentFormat.OpenXml.Lite.WordprocessingML.Word.Types;

namespace Samples.Word
{
    class Charts
    {
        public static void Create()
        {
            WB.Document doc = DocumentManager.Instance.CreateWordDocument();
            
            EB.Workbook wb = DocumentManager.Instance.CreateSpreadsheet();
            EB.Worksheet ws = wb.CreateWorksheet("sheet1", null);

            #region Create Chart Descriptor

            ChartDescriptor descriptor = new ChartDescriptor()
            {
                Unit = "%",
                Title = "Sample Chart",
                Series = new List<Serie>(),
                XValues = new string[]{"Category1", "Category2", "Category3", "Category4"}
            };

            Serie s1 = new Serie()
            {
                Label = "Serie1",
                Color = System.Drawing.Color.Blue,
                References  = new Dictionary<string,string>(),
                YValues = new string[]{"30", "10", "40", "20"}
            };

            Serie s2 = new Serie()
            {
                Label = "Serie2",
                Color = System.Drawing.Color.Orange,
                References  = new Dictionary<string,string>(),
                YValues = new string[] { "13.5", "24.5","12", "50" }
            };

            descriptor.Series.Add(s1);
            descriptor.Series.Add(s2);

            #endregion

            #region Data

            for (int i = 0; i < descriptor.XValues.Length; ++i )
            {
                EWE.Cell c = ws.CreateCell(i + 1, 1);
                c.CellType = ET.ST_CellType.String;
                c.AddSimpleText(descriptor.XValues[i]);
            }

            for (int i = 0; i < descriptor.Series.Count; ++i)
            {
                Serie serie = descriptor.Series[i];
                for (int j = 0; j < serie.YValues.Length; ++j)
                {
                    EWE.Cell c = ws.CreateCell(j + 1, i + 2);
                    c.CellType = ET.ST_CellType.Number;
                    c.AddSimpleText(serie.YValues[j]);
                }

                serie.References.Add("x", "sheet1!$A$1:$A$4");
                serie.References.Add("y", "sheet1!$" + EWE.Cell.Resolve(i + 2) + "$1:$" + 
                    EWE.Cell.Resolve(i + 2) + "$" + serie.YValues.Length.ToString() + "");
            }

            #endregion

            ChartSpace chartSpace = SampleChartBuilder.CreateChart(descriptor);
            string chartId = doc.CreateChartElement(chartSpace);
            WD.Drawing drawing = CreateDrawingElement("Chart1", chartId);
            doc.CreateBody().AddParagraph().AddRun().AddElement(drawing);

            string excelId = doc.AddWorkbookFor(chartSpace, wb, "Excel1.xlsx");
            chartSpace.ExternalData = new ExternalData()
            {
                RelationshipId = excelId
            };

            doc.Save(@"samples\chart.docx");

            WB.Document parsed = null;
            if (DocumentManager.Instance.OpenWordDocument(@"samples\chart.docx", out parsed))
            {
                ChartSpace backSp = parsed.FindElement<ChartSpace>(chartId);
                EB.Workbook backWb = parsed.GetEmbeddedWorkbookFor(backSp, excelId);
                Console.WriteLine("Sample created and parsed succesfully!");
            }

            Console.ReadLine();
        }

        public static WD.Drawing CreateDrawingElement(string name, string relId)
        {
            var drawing = new WD.Drawing();
            drawing.Anchor = new WD.DrawingAnchor()
            {
                DistanceOnTop = 0,
                DistanceOnBottom = 0,
                DistanceOnLeft = 114300,
                DistanceOnRight = 114300,
                SimplePosition = false,
                RelativeHeight = 251659264,
                BehindDocument = false,
                Locked = false,
                LayoutInCell = true,
                AllowOverlap = true,
                Position = new WD.SimplePosition() { X = 0, Y = 0 },
                HorizontalPositioning = new WD.HorizontalPositioning()
                {
                    RelativeFrom = WT.ST_RelFromH.Column,
                    Element = new WD.HorizontalAlign() { Value = WT.ST_Align.Center }
                },
                VerticalPosition = new WD.VerticalPositioning()
                {
                    RelativeFrom = WT.ST_RelFromV.Line,
                    Element = new WD.AbsolutePositioningOffset() { Value = 285750 }
                },
                Extents = new WD.Extent()
                {
                    ExtentLength = 5486400,
                    ExtentWidth = 3200400
                },
                EffectExtents = new WD.EffectExtent()
                {
                    BottomEdge = 0,
                    LeftEdge = 0,
                    RightEdge = 0,
                    TopEdge = 0
                },
                WrapType = new WD.WrapTopAndBottom(),
                Properties = new WD.DrawingObjectProperties()
                {
                    Name = name,
                    Id = (uint)new Random().Next(10000)
                },
                GraphicProperties = new WD.GraphicFrameProperties(),
                Graphic = new WD.Graphic()
                {
                    Data = new WD.GraphicData()
                    {
                        Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart",
                        DrawingElement = new Chart()
                        {
                            RelationshipId = relId
                        }
                    }
                }
            };

            return drawing;
        }
    }
}
